
#import "GameManager.h"

int W=320;
int H=480;

@implementation GameManager

#pragma mark ============================= Init Methods ================================

+ (GameManager*) getInstance  {
    
    static GameManager* gameManager;
		
	if (!gameManager) {
        gameManager = [[GameManager alloc] init];
		[gameManager preloader];            
	}
	    
    return gameManager;
}

- (void) preloader {        
    [self setOGLProjection];    
    state = LOAD_GAME;
}

- (void) loadGame {
    //Load level data here
}

#pragma mark ============================= Game Handler ===============================

- (void) touchBegan: (CGPoint) p {      
    NSLog(@"Touch: %f %f", p.x, p.y);
}

- (void) touchMoved: (CGPoint) p {
    [self touchBegan: p];      
}

- (void) drawStatesWithFrame: (CGRect) frame { 
    W = frame.size.width;
    H = frame.size.height; 
    switch (state) {
        case LOAD_GAME: 
            [self loadGame];
            state = PLAY_GAME;
            break;  
        case PLAY_GAME:
            [self playGame];
            break;           
        default: NSLog(@"ERROR: Unknown state: %i", state);
            break;
    }    
}	 

- (void) playGame {    
    timer++;                 
          
    static float z = 0; z += 0.1;
    glLoadIdentity();
    GLKMatrix4 glm = GLKMatrix4MakeLookAt(0, 0, z, 
                                          0, 0, z-1, 
                                          0, 1, 0); 
    glMultMatrixf(glm.m);   
    
    [self drawOGLCube];
} 

#pragma mark ============================= OGL Methods ===============================

- (void) setOGLProjection {
    glLoadIdentity();
    int w = W;
    int h = H; 
    
    //Set View
    glMatrixMode(GL_PROJECTION);     
    float zNear = 0.1; 
    float zFar = 2500;    
    float fieldOfViewAngle = 45;
    float top = zNear * tan(M_PI * fieldOfViewAngle / w);
    float bottom = -top;
    float left = bottom * w / h;
    float right = top * w / h;    
    glFrustumf(left, right, bottom, top, zNear, zFar); 
    
    glMatrixMode(GL_MODELVIEW);
    glEnableClientState(GL_VERTEX_ARRAY);    
    glEnable(GL_DEPTH_TEST); 
    glDepthFunc(GL_LESS);
    
    glEnable(GL_LIGHTING);      
    glEnable(GL_COLOR_MATERIAL);    
    glEnable(GL_LIGHT0);
    GLfloat color0[ ] = {1, 1, 1, 1}; 
    glLightfv(GL_LIGHT0, GL_DIFFUSE, color0);     
    GLfloat light_position0[ ] = {0, 1, 0, 0};
    glLightfv(GL_LIGHT0, GL_POSITION, light_position0);
} 

- (void) drawOGLCube {    
    
    GLfloat vertices[ ] = {
        -1, -1,  1, 
        1, -1,  1,
        -1,  1,  1,
        1,  1,  1,
        
        -1, -1, -1, 
        -1,  1, -1,
        1, -1, -1,
        1,  1, -1,
        
        -1,  1,  1, 
        1,  1,  1,
        -1,  1, -1,
        1,  1, -1,
        
        -1, -1,  1, 
        -1, -1, -1,
        1, -1,  1,
        1, -1, -1,
        
        -1, -1,  1, 
        -1,  1,  1,
        -1, -1, -1,
        -1,  1, -1,
        
        1, -1, -1, 
        1,  1, -1,
        1, -1,  1,
        1,  1,  1  
    };    
    
    GLfloat normals[ ] = {
        0,  0,  1, 
        0,  0,  1,
        0,  0,  1,
        0,  0,  1,
        
        0,  0, -1, 
        0,  0, -1,
        0,  0, -1,
        0,  0, -1,
        
        0,  1,  0, 
        0,  1,  0,
        0,  1,  0,
        0,  1,  0,
        
        0, -1,  0, 
        0, -1,  0,
        0, -1,  0,
        0, -1,  0,
        
        -1,  0,  0, 
        -1,  0,  0,
        -1,  0,  0,
        -1,  0,  0,
        
        1,  0,  0, 
        1,  0,  0,
        1,  0,  0,
        1,  0,  0   
    };
    
    int verticesLength = sizeof(vertices) / sizeof(GLfloat);
    
    glEnableClientState(GL_NORMAL_ARRAY);          
    glEnable(GL_NORMALIZE);     
    
    glEnable(GL_CULL_FACE); 
    glCullFace(GL_BACK);    
    
    glVertexPointer(3, GL_FLOAT, 0, vertices);      
    glNormalPointer(GL_FLOAT, 0, normals);
    
    glColor4f(1, 1, 0, 1); 
    
    glPushMatrix();  
    glTranslatef(0, 0, -7);
    static int angle = 0; angle += 2;
    glRotatef(angle, 1, 1, 0);    
    glDrawArrays(GL_TRIANGLE_STRIP, 0, verticesLength/3);      
    glPopMatrix();
    
    glDisableClientState(GL_NORMAL_ARRAY);
    glDisable(GL_NORMALIZE);     
    glDisable(GL_CULL_FACE);     
}

#pragma mark ============================= Helper Methods ===============================

- (void) setState: (int) stt {
    state = stt;
}

- (int) getRndBetween: (int) bottom and: (int) top {		
	int rnd = bottom + (arc4random() % (top+1-bottom)); 
	return rnd;
} 

- (void) dealloc {        
    [super dealloc];
}

@end
